package com.xhg.mqtt.util;

import com.sun.org.apache.xml.internal.security.utils.Base64;
import com.xhg.mqtt.constant.MqttConstants;
import com.xhg.mqtt.templet.PahoTlsExample;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;

/**
 * ssl认证管理管理
 * @Description 
 * @author E.T
 * @date 2018-07-21 15:13
 * @updateby
 * @updatedate
 * @version 1.0
 * @since 1.0
 */
public class SSLSocketManager {

    public static SSLSocketFactory getSSLSocktet(String pwd) throws Exception {
        // CA certificate is used to authenticate server
        CertificateFactory cAf = CertificateFactory.getInstance("X.509");
        InputStream inputstream = PahoTlsExample.class.getResourceAsStream(MqttConstants.CAPATH);
        X509Certificate ca = (X509Certificate) cAf.generateCertificate(inputstream);
        KeyStore caKs = KeyStore.getInstance("JKS");
        caKs.load(null, null);
        caKs.setCertificateEntry("ca-certificate", ca);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
        tmf.init(caKs);

        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        InputStream crtInputstream = PahoTlsExample.class.getResourceAsStream(MqttConstants.CRTPATH);
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(crtInputstream);

        crtInputstream.close();
        // client key and certificates are sent to server so it can authenticate
        // us
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(null, null);
        ks.setCertificateEntry("certificate", caCert);
        ks.setKeyEntry("private-key", getPrivateKey(MqttConstants.KEYPATH), pwd.toCharArray(),
                new Certificate[]{caCert}  );
        KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
        kmf.init(ks, pwd.toCharArray());

        // finally, create SSL socket factory
        SSLContext context = SSLContext.getInstance("TLSv1");

        context.init(kmf.getKeyManagers(),tmf.getTrustManagers(), new SecureRandom());

        return context.getSocketFactory();
    }

    private static PrivateKey getPrivateKey(String path) throws Exception{

//        Base64 base64=new Base64();
        byte[] buffer=   Base64.decode(getPem(path));

        PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer);
        KeyFactory keyFactory= KeyFactory.getInstance("RSA");
        return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);

    }

    private static String getPem(String path) throws Exception{
        InputStream inputstream = PahoTlsExample.class.getResourceAsStream(path);
        BufferedReader br= new BufferedReader(new InputStreamReader(inputstream));
        String readLine= null;
        StringBuilder sb= new StringBuilder();
        while((readLine= br.readLine())!=null){
            if(readLine.charAt(0)=='-'){
                continue;
            }else{
                sb.append(readLine);
                sb.append('\r');
            }
        }
        inputstream.close();
        return sb.toString();
    }
}
